/**
  ******************************************************************************
  * File Name          : MODBUS Hold input 【0x03 0x06 0x10】
  * Auther             : xifeng.yao@qq.com
  * Description        : Code for modbus applications
  ******************************************************************************
  * @attention
  * if(应用中 不需要用到保持寄存器(Hold))
  * {
  *   不要将这个.c文件，加入工程中编译;
  * }
  * else if(应用中 需要用到保持寄存器(Hold))
  * { 
  *   必须将这个.c文件，加入工程中编译;
  *   通过全局变量【ucRegHoldBuf】进行数据交互;
  * }
  *
  * @special:
  * 对应头文件中包含全局变量 【ucRegHoldBuf】 中的数据，请在应用线程中填充、修改、保存。
  * 
  * 
  ********/
	
/* Includes ------------------------------------------------------------------*/
#include <string.h>

#include "litemodbusBase.h"
#include "liteModbus_HoldReg.h"


uint16_t usRegHoldBuf[HOLD_REG_SIZE];  //变量表

/**
  * @brief  Modbus 0x03 0x04 0x06 0x10 协议解析 
  * @param  *response    指向数据帧，帧头
             int_value   0x03,0x04 读协议，需要应答的数据 
            *ext_value   0x06,0x10 写协议，需要返回的数据 
  * @retval true=解析完成，下一步应答
            false=未解析完成，下一个寄存器地址
  */
extern bool Modbus_Hold_Addr_Analy(uint8_t* response, int int_value, void* ext_value);

/**
  * @brief  
  * @param  modbus 数据结构体
  * @retval true or false
  */                              
bool Modbus_HoldReg_Analy(char* input) 
{
  ModbusFormat* data = (ModbusFormat*)input;
  
  uint16_t addrbuff = (uint16_t)(data->addr[0])<<8 | data->addr[1]; //小端地址,解析用临时变量
  bool     bitresult; //解析返回状态
  
  /*
    以下代码是针对变量地址解析，且按照一组连续变量地址进行解析模板
	
	  实际应用中可能会有分多段变量地址的情况，那么需要使用者自行修改
	  每个变量地址【addrbuff】调用【Modbus_Hold_Addr_Analy】处理即可。
  */
#if HOLD_REG_STARTADDR
  if(addrbuff < HOLD_REG_STARTADDR)  {ERR_ADDR(input)   return true;}
  addrbuff -= HOLD_REG_STARTADDR;
#endif
  do{
    if(addrbuff > HOLD_REG_SIZE)  {ERR_ADDR(input)   return true;}
    
    bitresult = Modbus_Hold_Addr_Analy((uint8_t*)data, usRegHoldBuf[addrbuff], &usRegHoldBuf[addrbuff]); //对应【地址addrbuff】与【变量usRegHoldBuf】关系
    addrbuff++;  
  }while(!bitresult);
  
  return true;
}
